package com.zx._02_thread.线程池;

import com.zx.common.util.ThreadUtil;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class 线程回收时机演示 {

    final static ThreadPoolExecutor pool = new ThreadPoolExecutor(
            5,              // 核心5
            10,         // 最大10
            10L, TimeUnit.SECONDS,// 线程存活10S
            new LinkedBlockingQueue<Runnable>(1));//容量1

    public static void main(final String[] args) throws Exception {
        // 开启监控
        monitor();

        // 提交11个任务，让线程池打满
        for (int i = 0; i < 11; i++) {
            final int idx = i + 1;
            pool.execute(() -> {
                run(idx);
            });
        }
        //  第一次观察，任务结束(5S)，再过10S后，回收非核心【注释掉下面的代码】

        //  第二次观察，任务结束(5S)，每1s添加一个任务【模拟任务量低于核心数】，
        //  任务新增的期间，非核心不回收
        //  没有新任务时，非核心才开始回收
        ThreadUtil.sleep(6L);
        log.info("任务全部结束了~~~~");

        for (int i = 0; i < 10; i++) {
            final int idx = i + 1;
            pool.execute(() -> {
                run(idx);
            });
            ThreadUtil.sleep(1L);
        }
        /* 日志如下
2021-08-23 11:17:07.356 [pool-1-thread-3] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>3
2021-08-23 11:17:07.355 [pool-1-thread-8] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>9
2021-08-23 11:17:07.355 [pool-1-thread-1] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>1
2021-08-23 11:17:07.355 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=0, ActiveCount=0, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:07.356 [pool-1-thread-9] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>10
2021-08-23 11:17:07.355 [pool-1-thread-5] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>5
2021-08-23 11:17:07.356 [pool-1-thread-7] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>8
2021-08-23 11:17:07.355 [pool-1-thread-4] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>4
2021-08-23 11:17:07.356 [pool-1-thread-2] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>2
2021-08-23 11:17:07.356 [pool-1-thread-10] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>11
2021-08-23 11:17:07.355 [pool-1-thread-6] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>7
2021-08-23 11:17:08.374 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=10, KeepAliveTime=10, QueueSize=1
2021-08-23 11:17:09.378 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=10, KeepAliveTime=10, QueueSize=1
2021-08-23 11:17:10.386 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=10, KeepAliveTime=10, QueueSize=1
2021-08-23 11:17:11.395 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=10, KeepAliveTime=10, QueueSize=1
2021-08-23 11:17:12.367 [pool-1-thread-3] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<3
2021-08-23 11:17:12.367 [pool-1-thread-5] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<5
2021-08-23 11:17:12.367 [pool-1-thread-4] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<4
2021-08-23 11:17:12.367 [pool-1-thread-1] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<1
2021-08-23 11:17:12.367 [pool-1-thread-8] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<9
2021-08-23 11:17:12.367 [pool-1-thread-7] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<8
2021-08-23 11:17:12.367 [pool-1-thread-9] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<10
2021-08-23 11:17:12.367 [pool-1-thread-10] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<11
2021-08-23 11:17:12.367 [pool-1-thread-2] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<2
2021-08-23 11:17:12.367 [pool-1-thread-6] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<7
2021-08-23 11:17:12.368 [pool-1-thread-3] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>6
2021-08-23 11:17:12.368 [pool-1-thread-5] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>1
2021-08-23 11:17:12.367 [main] INFO  com.zx._02_thread.线程池.线程回收时机演示 - 任务全部结束了~~~~

######这是新的任务
2021-08-23 11:17:12.398 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=2, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:13.378 [pool-1-thread-4] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>2
2021-08-23 11:17:13.409 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=3, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:14.387 [pool-1-thread-1] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>3
2021-08-23 11:17:14.419 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=4, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:15.390 [pool-1-thread-9] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>4
2021-08-23 11:17:15.421 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=5, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:16.396 [pool-1-thread-8] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>5
2021-08-23 11:17:16.428 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=6, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:17.383 [pool-1-thread-5] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<1
2021-08-23 11:17:17.383 [pool-1-thread-3] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<6
2021-08-23 11:17:17.399 [pool-1-thread-7] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>6
2021-08-23 11:17:17.431 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=5, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:18.392 [pool-1-thread-4] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<2
2021-08-23 11:17:18.407 [pool-1-thread-10] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>7
2021-08-23 11:17:18.438 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=5, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:19.391 [pool-1-thread-1] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<3
2021-08-23 11:17:19.422 [pool-1-thread-2] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>8
2021-08-23 11:17:19.453 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=5, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:20.403 [pool-1-thread-9] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<4
2021-08-23 11:17:20.433 [pool-1-thread-6] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>9
2021-08-23 11:17:20.465 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=5, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:21.406 [pool-1-thread-8] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<5
2021-08-23 11:17:21.438 [pool-1-thread-5] INFO  com.zx._02_thread.线程池.线程回收时机演示 - >>>>>10  ### 从这里开始就没有新的任务提交给线程池了，线程就进入等待状态了
2021-08-23 11:17:21.470 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=5, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:22.404 [pool-1-thread-7] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<6
2021-08-23 11:17:22.483 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=4, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:23.410 [pool-1-thread-10] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<7
2021-08-23 11:17:23.492 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=3, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:24.425 [pool-1-thread-2] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<8
2021-08-23 11:17:24.504 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=2, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:25.442 [pool-1-thread-6] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<9
2021-08-23 11:17:25.518 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=1, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:26.441 [pool-1-thread-5] INFO  com.zx._02_thread.线程池.线程回收时机演示 - <<<<<10
## 新的任务已经执行完了，后面就开始回收非核心了
2021-08-23 11:17:26.518 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=10, ActiveCount=0, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:27.520 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=9, ActiveCount=0, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:28.529 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=8, ActiveCount=0, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:29.536 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=7, ActiveCount=0, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:30.537 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=6, ActiveCount=0, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:31.547 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=5, ActiveCount=0, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:32.563 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=5, ActiveCount=0, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:33.567 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=5, ActiveCount=0, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:34.578 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=5, ActiveCount=0, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:35.579 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=5, ActiveCount=0, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:36.590 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=5, ActiveCount=0, KeepAliveTime=10, QueueSize=0
2021-08-23 11:17:37.595 [Thread-0] INFO  com.zx._02_thread.线程池.线程回收时机演示 - CorePoolSize=5, PoolSize=5, ActiveCount=0, KeepAliveTime=10, QueueSize=0

Process finished with exit code -1

        */

    }

    private static void run(int idx) {
        log.info(">>>>>{}", idx);
        ThreadUtil.sleep(5L);
        log.info("<<<<<{}", idx);
    }

    private static void monitor() throws Exception {
        new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                try {
                    log.info("CorePoolSize={}, PoolSize={}, ActiveCount={}, KeepAliveTime={}, QueueSize={}",
                            pool.getCorePoolSize(),
                            pool.getPoolSize(),
                            pool.getActiveCount(),
                            pool.getKeepAliveTime(TimeUnit.SECONDS),
                            pool.getQueue().size()
                    );
                    ThreadUtil.sleep(1L);
                } catch (Exception e) {
                }
            }
        }).start();

    }


}
